package com.java.star.mall.front.service.impl;

import com.java.star.mall.common.constant.data.CartConstant;
import com.java.star.mall.common.response.StatusCode;
import com.java.star.mall.common.utils.Asserts;
import com.java.star.mall.front.dao.cache.CartRepository;
import com.java.star.mall.front.dao.mapper.ProductMapper;
import com.java.star.mall.front.pojo.authentication.CurrentPrincipal;
import com.java.star.mall.front.pojo.entity.Product;
import com.java.star.mall.front.pojo.param.AddCartParam;
import com.java.star.mall.front.pojo.param.UpdateCartCheckedParam;
import com.java.star.mall.front.pojo.param.UpdateCartNumParam;
import com.java.star.mall.front.pojo.po.CartPO;
import com.java.star.mall.front.pojo.vo.CartVO;
import com.java.star.mall.front.properties.ImageProperties;
import com.java.star.mall.front.service.CartService;
import com.java.star.mall.front.util.CurrentPrincipalUtils;
import io.jsonwebtoken.lang.Collections;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 购物车Service实现类
 */
@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private CartRepository cartRepository;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private ImageProperties imageProperties;

    @Override
    public List<CartVO> listCart() {
        //获取当前用户信息
        CurrentPrincipal currentPrincipal = CurrentPrincipalUtils.getCurrentPrincipal();

        //查询当前用户的购物车列表
        List<CartPO> cartPOList = cartRepository.listCart(currentPrincipal.getId());

        //装填VO数据
        List<CartVO> cartVOList = cartPOList.stream().map(cartPO -> {
            CartVO cartVo = new CartVO();
            BeanUtils.copyProperties(cartPO, cartVo);
            cartVo.setProPic(imageProperties.getUrl() + cartPO.getProPic());
            return cartVo;
        }).collect(Collectors.toList());

        return cartVOList;
    }

    @Override
    public void addToCart(AddCartParam addCartParam) {
        //获取当前用户信息
        CurrentPrincipal currentPrincipal = CurrentPrincipalUtils.getCurrentPrincipal();

        //查询该商品是否已经加入过购物车，如果没加入，再新增，如果加入过，只需要修改数量
        CartPO cartItem = cartRepository.getCartItem(currentPrincipal.getId(), addCartParam.getProductId());
        if (cartItem == null) {
            //如果不存在，则查询当前商品信息，并加入到购物车
            Product product = productMapper.getProductById(addCartParam.getProductId());
            Asserts.isTrue(product == null, StatusCode.RESPONSE_PACK_ERROR, "商品不存在");
            cartItem = new CartPO();
            BeanUtils.copyProperties(product, cartItem);
            cartItem.setChecked(true);
            cartItem.setNum(addCartParam.getNum());
        } else {
            //如果存在，则做数量上的更改
            cartItem.setNum(cartItem.getNum() + addCartParam.getNum());
        }
        cartRepository.addCartItem(currentPrincipal.getId(), addCartParam.getProductId(), cartItem);
    }

    @Override
    public void batchChangeChecked(Boolean checked) {
        //获取当前用户信息
        CurrentPrincipal currentPrincipal = CurrentPrincipalUtils.getCurrentPrincipal();

        //获取当前用户的购物车列表
        List<CartPO> cartPOList = cartRepository.listCart(currentPrincipal.getId());
        Asserts.isTrue(cartPOList == null, StatusCode.RESPONSE_PACK_ERROR, "购物车不存在");

        //更改选中状态
        Map<String, CartPO> cartPOMap = cartPOList.stream().peek(cartPO -> cartPO.setChecked(checked))
                .collect(Collectors.toMap(cartPO -> cartPO.getId().toString(), cartPO -> cartPO));

        //重新存入Redis
        cartRepository.batchAddCartItem(currentPrincipal.getId(), cartPOMap);
    }

    @Override
    public void changeChecked(UpdateCartCheckedParam updateCartCheckedParam) {
        //获取当前用户信息
        CurrentPrincipal currentPrincipal = CurrentPrincipalUtils.getCurrentPrincipal();

        //从购物车中获取当前购物项
        CartPO cartItem = cartRepository.getCartItem(currentPrincipal.getId(), updateCartCheckedParam.getProductId());
        Asserts.isTrue(cartItem == null, StatusCode.RESPONSE_PACK_ERROR, "购物项不存在");

        //修改选中状态
        cartItem.setChecked(updateCartCheckedParam.getChecked());

        //重新存入Redis
        cartRepository.addCartItem(currentPrincipal.getId(), updateCartCheckedParam.getProductId(), cartItem);
    }

    @Override
    public void changeNum(UpdateCartNumParam updateCartNumParam) {
        //获取当前用户信息
        CurrentPrincipal currentPrincipal = CurrentPrincipalUtils.getCurrentPrincipal();

        //获取当前要修改的购物项
        CartPO cartItem = cartRepository.getCartItem(currentPrincipal.getId(), updateCartNumParam.getProductId());
        Asserts.isTrue(cartItem == null, StatusCode.RESPONSE_PACK_ERROR, "购物项不存在");

        //如果为添加购物项数量操作
        if (CartConstant.OPERATION_ADD.equals(updateCartNumParam.getOperation())) {
            int sum = cartItem.getNum() + updateCartNumParam.getNum();
            cartItem.setNum(sum);
            //重新存入Redis
            cartRepository.addCartItem(currentPrincipal.getId(), updateCartNumParam.getProductId(), cartItem);
            return;
        }

        //如果为减少购物项数量操作
        if (CartConstant.OPERATION_DECREASE.equals(updateCartNumParam.getOperation())) {
            int diff = cartItem.getNum() - updateCartNumParam.getNum();
            Asserts.isTrue(diff <=0, StatusCode.APP_ERROR, "购物项的数量不能小于1");
            cartItem.setNum(diff);
            //重新存入Redis
            cartRepository.addCartItem(currentPrincipal.getId(), updateCartNumParam.getProductId(), cartItem);
        }
    }

    @Override
    public void deleteToCart(Integer productId) {
        //获取当前用户信息
        CurrentPrincipal currentPrincipal = CurrentPrincipalUtils.getCurrentPrincipal();

        //从缓存中删除
        cartRepository.deleteCartItem(currentPrincipal.getId(), productId);
    }

    @Override
    public List<CartVO> listCheckedItem(Integer userId) {
        //查询用户购物车
        List<CartPO> cartPOList = cartRepository.listCart(userId);
        Asserts.isTrue(Collections.isEmpty(cartPOList), StatusCode.APP_ERROR, "购物车没有商品");

        //过滤出已选中的购物商品
        List<CartVO> orderItemVOList = cartPOList.stream().filter(CartPO::getChecked).map(cartPO -> {
            CartVO cartVO = new CartVO();
            BeanUtils.copyProperties(cartPO, cartVO);
            cartVO.setProPic(imageProperties.getUrl() + cartVO.getProPic());
            return cartVO;
        }).collect(Collectors.toList());

        return orderItemVOList;
    }
}
